﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace eTerm.PlugIn.DETRPlugIn
{
    using System.Text.RegularExpressions;
    using eTerm.NetSocket.Base;
    using eTerm.MsSql.DbProvider;


    public class AnalysisTSL {
        public string TslStr = string.Empty;

        public TSL[] ParseTSL() {
            string orgString = TslStr;
            List<TSL> datas = new List<TSL>();
            string pattern = @"\d{3}\-\d{10}\s+((VOID\s+(\d+\s+)?(\d{2}[A-Z]{3}\s+)?\w{6})|(C\d\s+[A-Z]{3}\s+[A-Z]{3}\s+\w{6}\s+\d{5})|((C\d\s+)?[A-Z]{3}\s+[A-Z]{3}\s+\d+\.\d{2}\s+\d+\.\d{2}\s+\d+\.\d{2}\s+\w{6}\s+\d{5}))";
            string pattern1 = @"\d{3}\-\d{10}\s+(BSP\s+DATA\s+CANCELLED\s+\!)\s+\w{6}()()()()()()";
            foreach (string e in orgString.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
            {
                TslStr = e;
                List<Match> mc = Regex.Matches(this.TslStr, pattern).Cast<Match>().Union(Regex.Matches(this.TslStr,pattern1).Cast<Match>()).ToList();
                foreach (Match m in mc)
                {
                    string tmp = m.Value.ToString();
                    TSL t = new TSL();
                    t.TicketNo = Regex.Match(tmp, @"\d{3}\-\d{10}").Value.ToString();
                    if (tmp.IndexOf("VOID") >= 0)
                    {
                        t.Pnr = Regex.Match(tmp, @"\s\w{6}\s").Value.ToString().Trim();
                        t.Status = "V";
                    }
                    else if (Regex.IsMatch(m.Value.ToString(), @"(BSP\s+DATA\s+CANCELLED\s+\!)", RegexOptions.IgnoreCase | RegexOptions.Multiline)) {
                        t.Status = @"I";
                        t.Pnr = Regex.Match(tmp, @"\s\w{6}\s").Value.ToString().Trim();
                    }
                    else
                    {
                        t.Orig = Regex.Matches(Regex.Match(tmp, @"\s+[A-Z]{3}\s+[A-Z]{3}\s+").Value.ToString(), "[A-Z]{3}")[0].Value.ToString();
                        t.Dest = Regex.Matches(Regex.Match(tmp, @"\s+[A-Z]{3}\s+[A-Z]{3}\s+").Value.ToString(), "[A-Z]{3}")[1].Value.ToString();
                        t.Pnr = Regex.Match(tmp, @"[A-Z]\w{5}").Value.ToString();
                        t.Status = "T";
                        if (Regex.IsMatch(tmp, @"\sC\d\s"))
                        {
                            if (!Regex.IsMatch(tmp, @"\sC1\s"))
                            {
                                t.IsConjunction = true;
                                t.Collection = "0";
                                t.Tax = "0";
                                t.Commission = "0";
                            }
                            else
                            {
                                t.IsConjunction = false;
                                t.Collection = Regex.Matches(tmp, @"\d+\.\d{2}")[0].Value.ToString();
                                t.Tax = Regex.Matches(tmp, @"\d+\.\d{2}")[1].Value.ToString();
                                t.Commission = Regex.Matches(tmp, @"\d+\.\d{2}")[2].Value.ToString();
                            }
                        }
                        else
                        {
                            t.IsConjunction = false;
                            t.Collection = Regex.Matches(tmp, @"\d+\.\d{2}")[0].Value.ToString();
                            t.Tax = Regex.Matches(tmp, @"\d+\.\d{2}")[1].Value.ToString();
                            t.Commission = Regex.Matches(tmp, @"\d+\.\d{2}")[2].Value.ToString();
                        }
                    }
                    //Array.Resize<TSL>(ref datas, datas.Length + 1);
                    //datas[datas.Length - 1] = t;
                    datas.Add(t);
                }
            }
            return datas.ToArray();
        }
    }

    [Serializable]
    public class TSL : BaseBinary<TSL>
    {
        private string _Collection = string.Empty;
        private string _Commission = string.Empty;
        private string _Dest = string.Empty;
        private bool _IsConjunction = false;
        private string _Orig = string.Empty;
        private string _Pnr = string.Empty;
        private string _Status = string.Empty;
        private string _Tax = string.Empty;
        private string _TicketNo = string.Empty;
        private string _Type = string.Empty;

        public string Collection {
            get {
                return this._Collection;
            }
            set {
                this._Collection = value;
            }
        }

        public DetrInfo DetrInfoValue { get; set; }

        public string Commission {
            get {
                return this._Commission;
            }
            set {
                this._Commission = value;
            }
        }

        public string Dest {
            get {
                return this._Dest;
            }
            set {
                this._Dest = value;
            }
        }

        public bool IsConjunction {
            get {
                return this._IsConjunction;
            }
            set {
                this._IsConjunction = value;
            }
        }

        public string Orig {
            get {
                return this._Orig;
            }
            set {
                this._Orig = value;
            }
        }

        public string Pnr {
            get {
                return this._Pnr;
            }
            set {
                this._Pnr = value;
            }
        }

        public string Status {
            get {
                return this._Status;
            }
            set {
                this._Status = value;
            }
        }

        public string Tax {
            get {
                return this._Tax;
            }
            set {
                this._Tax = value;
            }
        }

        public string TicketNo {
            get {
                return this._TicketNo;
            }
            set {
                this._TicketNo = value;
            }
        }

        public string Type {
            get {
                return this._Type;
            }
            set {
                this._Type = value;
            }
        }
    }

    [Serializable]
    public class DetrFltSeg : BaseBinary<DetrFltSeg>
    {
        private string _Airline = string.Empty;
        private string _Arrival = string.Empty;
        private string _ArrivalDate = string.Empty;
        private string _ArrivalTime = string.Empty;
        private string _Carbin = string.Empty;
        private string _Departure = string.Empty;
        private string _DepartureDate = string.Empty;
        private string _DepartureTime = string.Empty;
        private string _FlightNo = string.Empty;
        private int _SegId = 0;
        private DetrStatus _Status = DetrStatus.PENDDING;

        public string Airline {
            get {
                return this._Airline;
            }
            set {
                this._Airline = value;
            }
        }

        public string Arrival {
            get {
                return this._Arrival;
            }
            set {
                this._Arrival = value;
            }
        }

        public string ArrivalDate {
            get {
                return this._ArrivalDate;
            }
            set {
                this._ArrivalDate = value;
            }
        }

        public string ArrivalTime {
            get {
                return this._ArrivalTime;
            }
            set {
                this._ArrivalTime = value;
            }
        }

        public string Carbin {
            get {
                return this._Carbin;
            }
            set {
                this._Carbin = value;
            }
        }

        public string Departure {
            get {
                return this._Departure;
            }
            set {
                this._Departure = value;
            }
        }

        public string DepartureDate {
            get {
                return this._DepartureDate;
            }
            set {
                this._DepartureDate = value;
            }
        }

        public string DepartureTime {
            get {
                return this._DepartureTime;
            }
            set {
                this._DepartureTime = value;
            }
        }

        public string FlightNo {
            get {
                return this._FlightNo;
            }
            set {
                this._FlightNo = value;
            }
        }

        public int SegId {
            get {
                return this._SegId;
            }
            set {
                this._SegId = value;
            }
        }

        public DetrStatus Status {
            get {
                return this._Status;
            }
            set {
                this._Status = value;
            }
        }
    }


    [Serializable]
    public class DetrInfo : BaseBinary<DetrInfo>
    {
        private string _Airline = string.Empty;
        private string _Carbin = string.Empty;
        private string _Commission = string.Empty;
        private string _Fare = string.Empty;
        private string _Flight = string.Empty;
        private string _FltDate = string.Empty;
        private DetrFltSeg[] _FltSeg=new DetrFltSeg[]{};
        private bool _IsConjunction = false;
        private string _Passenger = string.Empty;
        private string _Pnr = string.Empty;
        private string _Segment = string.Empty;
        private DetrStatus _Status = DetrStatus.PENDDING;
        private string _Tax = string.Empty;
        private string _TicketDate = string.Empty;
        private string _TicketNo = string.Empty;
        private string _Type = string.Empty;

        public string Airline {
            get {
                return this._Airline;
            }
            set {
                this._Airline = value;
            }
        }

        public string Carbin {
            get {
                return this._Carbin;
            }
            set {
                this._Carbin = value;
            }
        }

        public string Commission {
            get {
                return this._Commission;
            }
            set {
                this._Commission = value;
            }
        }

        public string Fare {
            get {
                return this._Fare;
            }
            set {
                this._Fare = value;
            }
        }

        public string Flight {
            get {
                return this._Flight;
            }
            set {
                this._Flight = value;
            }
        }

        public string FltDate {
            get {
                return this._FltDate;
            }
            set {
                this._FltDate = value;
            }
        }

        public DetrFltSeg[] FltSeg {
            get {
                return this._FltSeg;
            }
            set {
                this._FltSeg = value;
            }
        }

        public bool IsConjunction {
            get {
                return this._IsConjunction;
            }
            set {
                this._IsConjunction = value;
            }
        }

        public string Passenger {
            get {
                return this._Passenger;
            }
            set {
                this._Passenger = value;
            }
        }

        public string Pnr {
            get {
                return this._Pnr;
            }
            set {
                this._Pnr = value;
            }
        }

        public string Segment {
            get {
                return this._Segment;
            }
            set {
                this._Segment = value;
            }
        }

        public DetrStatus Status {
            get {
                return this._Status;
            }
            set {
                this._Status = value;
            }
        }

        public string Tax {
            get {
                return this._Tax;
            }
            set {
                this._Tax = value;
            }
        }

        public string TicketDate {
            get {
                return this._TicketDate;
            }
            set {
                this._TicketDate = value;
            }
        }

        public string TicketNo {
            get {
                return this._TicketNo;
            }
            set {
                this._TicketNo = value;
            }
        }

        public string Type {
            get {
                return this._Type;
            }
            set {
                this._Type = value;
            }
        }
    }

    public class AnalysisDetr {
        private string _DetrStr = string.Empty;
        private string _TicketNo = string.Empty;

        public DetrInfo ParseDetr() {
            int i;
            DetrInfo di = new DetrInfo();
            DetrFltSeg[] dfs = new DetrFltSeg[0];
            string szLastCity = string.Empty;
            string s = this.DetrStr;
            di.TicketNo = this.TicketNo;
            if ((s.IndexOf("ET TICKET NUMBER IS NOT EXIST") >= 0) || (s.IndexOf("ET PASSENGER DATA NOT FOUND") >= 0)) {
                di.Status =  DetrStatus.NOTEXIST| DetrStatus.BEFORECOMPARE;
                return di;
            }
            string pattern = @"ISSUED BY:\s+\w+\s+\w+";
            di.Airline = Regex.Match(s, pattern).Value.ToString().Replace("ISSUED BY: ", "").Trim();
            if (s.IndexOf("BSP-D") >= 0) {
                di.Type = "D";
            }
            else if (s.IndexOf("BSP-I") >= 0) {
                di.Type = "I";
            }
            pattern = @"PASSENGER:\s.+EXCH:";
            di.Passenger = Regex.Match(s, pattern).Value.ToString();
            di.Passenger = di.Passenger.Replace("PASSENGER:", "").Replace("EXCH:", "").Trim();
            pattern = @"((FM)|(TO)):(\w|\s|/|\-|:)+\r";
            string[] seg = Regex.Match(s, pattern).Value.ToString().Split(new char[] { '\r' });
            foreach (string _seg in seg) {
                string _s = _seg;
                //if ((Regex.IsMatch(_s, @"(CHECKED\s+IN)|(LIFT\/BOARDED)|(VOID)", RegexOptions.IgnoreCase | RegexOptions.Multiline)))
                //{
                //    di.Status =  DetrStatus.USED;
                //}
                pattern = @"\d[A-Z]{3}\s+\w{2}\s+(\w{2}\s+)?((\d+)|(OPEN))\s+[A-Z]\s+((\d{2}[A-Z]{3})|(OPEN))\s+((\d{4})|[A-Z])";
                if (Regex.IsMatch(_s, pattern)) {
                    DetrFltSeg _fltSeg = new DetrFltSeg();
                    string[] _tmp = Regex.Match(_s, pattern).Value.ToString().Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                    if (_tmp.Length == 6) {
                        _fltSeg.SegId = Convert.ToInt32(_tmp[0].Substring(0, 1));
                        _fltSeg.Departure = _tmp[0].Substring(1);
                        _fltSeg.Airline = _tmp[1];
                        _fltSeg.FlightNo = _tmp[2];
                        _fltSeg.Carbin = _tmp[3];
                        _fltSeg.DepartureDate = _tmp[4];
                        _fltSeg.DepartureTime = _tmp[5];
                    }
                    else if (_tmp.Length == 7) {
                        _fltSeg.SegId = Convert.ToInt32(_tmp[0].Substring(0, 1));
                        _fltSeg.Departure = _tmp[0].Substring(1);
                        _fltSeg.Airline = "*" + _tmp[1];
                        _fltSeg.FlightNo = _tmp[3];
                        _fltSeg.Carbin = _tmp[4];
                        _fltSeg.DepartureDate = _tmp[5];
                        _fltSeg.DepartureTime = _tmp[6];
                    }
                    if (Regex.IsMatch(_s, @"OPEN FOR USE", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {//.IndexOf("OPEN FOR USE") >= 0) {
                        _fltSeg.Status = DetrStatus.OPENFORUSE;
                    }
                    else if (Regex.IsMatch(_s, @"NIL SUSPENDED", RegexOptions.IgnoreCase | RegexOptions.Multiline)) {
                        _fltSeg.Status = DetrStatus.OPENFORUSE| DetrStatus.SUSPENDED;
                    }
                    else if (Regex.IsMatch(_s, @"AIRPORT CNTL", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {
                        _fltSeg.Status = DetrStatus.OPENFORUSE | DetrStatus.AIRPORTCNTL;
                    }
                    else if (Regex.IsMatch(_s, @"REFUND", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {
                        _fltSeg.Status = DetrStatus.REFUND;
                    }
                    else if (Regex.IsMatch(_s, @"(USED\/FLOWN)|(CHECKED\s+IN)|(LIFT\/BOARDED)|(VOID)", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {
                        _fltSeg.Status = DetrStatus.USED;
                    }
                    //else if (Regex.IsMatch(_s, @"SUSPENDED", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    //{
                    //    _fltSeg.Status = DetrStatus.SUSPENDED;
                    //}
                    else
                    {
                        _fltSeg.Status = DetrStatus.PENDDING;
                    }
                    Array.Resize<DetrFltSeg>(ref dfs, dfs.Length + 1);
                    dfs[dfs.Length - 1] = _fltSeg;
                }
                else {
                    pattern = @"TO:\s[A-Z]{3}";
                    if (Regex.IsMatch(_s, pattern)) {
                        _s = Regex.Match(_s, pattern).Value.ToString();
                        pattern = "[A-Z]{3}";
                        szLastCity = Regex.Match(_s, pattern).Value.ToString();
                    }
                }
            }
            if (szLastCity.Length == 3) {
                if (dfs.Length > 0)
                {
                    dfs[dfs.Length - 1].Arrival = szLastCity;
                    for (i = 0; i < (dfs.Length - 1); i++)
                    {
                        dfs[i].Arrival = dfs[i + 1].Departure;
                    }
                }
            }
            di.FltSeg = dfs;

            if (di.FltSeg.Count(l => (l.Status & DetrStatus.REFUND)!=0) == di.FltSeg.Count()) {
                di.Status = DetrStatus.REFUND| DetrStatus.BEFORECOMPARE;
            }
            else if (di.FltSeg.Count(l => (l.Status & DetrStatus.USED)!=0) == di.FltSeg.Count()) {
                di.Status = DetrStatus.USED;
            }
            else
            {
                di.FltSeg.Select(l => l.Status).Distinct().ToList().ForEach(l => {
                    if ((int)(l & (DetrStatus.USED | DetrStatus.REFUND | DetrStatus.BEFORECOMPARE)) == 0)
                    {
                        if (di.Status == DetrStatus.PENDDING) {
                            di.Status = l;
                        } else {
                            di.Status = di.Status | l;
                        }
                    }
                });
            }


            return di;
        }

        public string DetrStr {
            get {
                return this._DetrStr;
            }
            set {
                this._DetrStr = value;
            }
        }

        public string TicketNo {
            get {
                return this._TicketNo;
            }
            set {
                this._TicketNo = value;
            }
        }
    }
}
